package fmglemmings;

import java.util.logging.Logger;
import java.util.LinkedList;
import java.io.*;
import java.util.*;

/**
 * A palya
 */
public class GameField implements RequestListener{
    /**
     * Le van-e pausolva a jatek? Ha igen, akkor nem reagal a bemenetre
     */
	private boolean paused;
	private static Logger logger = Logger.getLogger("fmglemmings");
	
    /**
     * Mapobjectek Listainak tombje. A tomb indexei a koordinatak, az adott helyen levo MapObjectek Listajat taroljak
     */
	private List[][] field;     //Mapobjectek Listainak tombje. A tomb indexei a koordinatak, az adott helyen levo MapObjectek Listajat taroljak
        public List mobjects;
    /**
     * palya szelessege
     */
        int mx; 
        public int getmx() {return mx;}
    /**
     * palya magassaga
     */
        int my;     //a palya mereteit taroljak
        public int getmy() {return my;}
    /**
     * Palyan levo + meg meg nem szuletett lemmingek szama
     */
        int numberOfLemmings=0;  //lemmingek osszes szama (szuletendo+palyan levo)
        public int getnumberOfLemmings() {return numberOfLemmings;}
    /**
     * celbaert lemmingek szama
     */
        int numberOfWinners=0;  //celbaert lemmingek szama
        public int getnumberOfWinners() {return numberOfWinners;}
    /**
     * felhasznalhato aso eszkoz szama
     */
        int digger;
        public int getdigger() {return digger;}
    /**
     * felhasznalhato repulo eszkoz szama
     */
        int flying;
        public int getflying() {return flying;}
    /**
     * felhasznalhato epito eszkoz szama
     */
        int builder;
        public int getbuilder() {return builder;}
    /**
     * felhasznalhato robbano eszkoz szama
     */
        int bomb;
        public int getbomb() {return bomb;}
    /**
     * felhasznalhato blokkolo eszkoz szama
     */
        int blocker;   //adott eszkozok szama
        public int getblocker() {return blocker;}
        
	/**
	 * A palya konstruktora
	 * @param palya Egy sztring ami egy letezo fajlra mutat amiben a palya van.
	 */
        public GameField(String palya)throws Exception{
            try {
                BufferedReader in = new BufferedReader(new FileReader(palya));
                String str, s;
                while ((str = in.readLine()) != null) {
//                  try{
                    StringTokenizer parser = new StringTokenizer(str); 
                    s=parser.nextToken();
                    if (s.equals("map")) {
                                mx = Integer.parseInt(parser.nextToken().trim());
                                my = Integer.parseInt(parser.nextToken().trim());
                                field=new List[mx][my];
                                s="bbb";
                    }
                    if (s.equals("digger")) {
                                digger = Integer.parseInt(parser.nextToken().trim());  
                                s="bbb";
                    }
                    if (s.equals("flying")) {
                                flying = Integer.parseInt(parser.nextToken().trim());  
                                s="bbb";
                    }
                    if (s.equals("builder")) {
                                builder = Integer.parseInt(parser.nextToken().trim()); 
                                s="bbb";
                    }
                    if (s.equals("blocker")) {
                                blocker = Integer.parseInt(parser.nextToken().trim());                              
                                s="bbb";
                    }
                    if (s.equals("bomb")) {
                                bomb = Integer.parseInt(parser.nextToken().trim());   
                                s="bbb";
                    }
                    if (s.equals("entrypoint")) {
				int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int n = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new Spawn(x,y,1,n));  
                                numberOfLemmings+=n;
                                s="bbb";
                    } 
                    if (s.equals("Lemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new Lemming(x,y,d)); 
                                numberOfLemmings++;
                                s="bbb";
                    }
                    if (s.equals("BlockerLemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new BlockerLemming(x,y,d));    
                                numberOfLemmings++;
                                s="bbb";
                    } 
                    if (s.equals("BomberLemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new BombLemming(x,y,d));    
                                numberOfLemmings++;
                                s="bbb";
                    } 
                    if (s.equals("FlyingLemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new FlyingLemming(x,y,d));   
                                numberOfLemmings++;
                                s="bbb";
                    } 
                    if (s.equals("DiggerLemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new DiggerLemming(x,y,d));     
                                numberOfLemmings++;
                                s="bbb";
                    } 
                    if (s.equals("BuilderLemming")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                int d = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new BuilderLemming(x,y,d));     
                                numberOfLemmings++;
                                s="bbb";
                    } 
                    if (s.equals("Stone")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                boolean d = !(parser.nextToken().equals("0"));
                                putObject(x,y,new Stone(x,y,1,d));  
                                s="bbb";
                    } 
                    if (s.equals("LeftLadderStone")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                boolean d = !(parser.nextToken().equals("0"));
                                putObject(x,y,new LeftLadderStone(x,y,1,d)); 
                                s="bbb";
                    } 
                    if (s.equals("RightLadderStone")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                boolean d = !(parser.nextToken().equals("0"));
                                putObject(x,y,new RightLadderStone(x,y,1,d));  
                                s="bbb";
                    } 
                    if (s.equals("Bridge")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                boolean d = !(parser.nextToken().equals("0"));
                                putObject(x,y,new Bridge(x,y,1,d));         
                                s="bbb";
                    } 
                    if (s.equals("exitpoint")) {
                                int x = Integer.parseInt(parser.nextToken().trim());
                                int y = Integer.parseInt(parser.nextToken().trim());
                                putObject(x,y,new Goal(x,y,1)); 
                                s="bbb";
                    }
		    if (s.equals("DeadLemming")) {
			    int x = Integer.parseInt(parser.nextToken().trim());
			    int y = Integer.parseInt(parser.nextToken().trim());
			    int d = Integer.parseInt(parser.nextToken().trim());
			    putObject(x,y,new DeadLemming(x,y,d));
                            s="bbb";
		    }
                    if (!s.equals("bbb")){
                        throw(new Exception("rossz fajlformatum"));
                    }
//                  }
//                  catch (/*NumberFormat*/Exception nfe) {logger.warning("Rossz fajlformatum");}
                }
                in.close();
            } 
            catch (IOException e) {logger.warning("Fajl olvasasi hiba");}
            
            mobjects=new LinkedList();  //mobjects kiuritese
            
            buildmobjects();
        }
	private void buildmobjects(){
            mobjects=new LinkedList();  //mobjects kiuritese
            for(int i=0;i<mx;i++)   //mobjects felepitese
                for (int j=0;j<my;j++){
                    if(field[i][j]!=null){
                        for (int k=0;k<field[i][j].size();k++){
                            MapObject mo=(MapObject)field[i][j].get(k);
                            mobjects.add(mo);
                        }
                    }
                }
        } 
	/**
     * MapObjectek automatikus mozgatasa. A Direction szerinti iranyba lepteti egy kockaval arrebb
     * @param obj Ezt az objektumot mozgatjuk a megfelelo iranyba
     */
	private void moveObject(MapObject obj) {       
            int x=obj.getX();       //Lekeri a jelenlegi koordinatait
            int y=obj.getY();
            int dir=obj.getDirection();     //Lekeri az iranyat, hogy arra mozgassa
            switch(dir){                    //Iranynak megfeleloen mozgatja
                case 1:                     //Balra-fel
                    x--;y--;                //Mindket koordinatat csokkenti
                    putObject(x,y,obj);     //A jatekmezon a megfelelo helyre teszi
                    removeObject(obj);      //Torli a regi helyerol
                    obj.setX(x);            //Az objektumon bel�l is megvaltoztatja a koordinatakat
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 3:                 //Jobbra-fel
                    x++;y--;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 4:                 //Balra
                    x--;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 6:                 //Jobbra
                    x++;        
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 7:                 //Balra-le
                    x--;y++;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 9:                 //Jobbra-le
                    x++;y++;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 10:                //Lefele (Megjegyezve hogy eddig balra ment, es majd erre kell folytatnia az eses utan a mozgast)
                    y++;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                case 11:                //Lefele (Megjegyezve hogy eddig jobbra ment, es majd erre kell folytatnia az eses utan a mozgast)
                    y++;
                    putObject(x,y,obj);
                    removeObject(obj);
                    obj.setX(x);
                    obj.setY(y);
                    logger.info("Lemming az "+x+", "+y+" koordinatakra mozgatva");
                    break;
                default:
                    logger.info("Lemmingnek nem letezo iranya van");
            
                
            }
            
	}
    /**
     * Az Objektum kovetkezo lepeset szamolja ki, es beallitja a megfelelo iranyt
     * @param mo Ennek az objektumnak az iranyat szamolja ki
     */
	private void testnextmove(MapObject mo) {
		int x,y,dir,nx,ny;
		x=mo.getX();
		y=mo.getY();
                dir=mo.getDirection();
                if ((dir==3)||(dir==6)||(dir==9)||(dir==11)){   //ha jobbra megy a lemming
                    if(!hastoptest(x,y+1)){                //ha nincs alatta talaj
                        mo.fallEvent();             //szol a lemmingnek, hogy esik
                        if(!hastoptest(x,y+1))mo.setDirection(11);        //bealitja a lefele iranyt, elterolva hogy jobbra megy majd tovabb
                    }
                    else{                           //Ha van alatta talaj
                        if (dir==11){
                            mo.setDirection(6);
                            mo.fallenEvent();      //Ha eddig esett, akkor foldeteres Eventet kuld a Lemmingnek
                        }
                        if ((lifttest(x,y+1))&&(!liftdir(x,y+1))){  //ha balra lejt� k� van alatta
                            if (blocktest(x+1,y+1)){         //jobbra-le blokkol� k� van
                                mo.setDirection(9);                                     //ett�l f�ggetlen�l be�ll�tja az ir�ny�t
                                mo.hitEvent((MapObject)field[x+1][y+1].get(0));         //elk�ldi a hiteventet   
                            }                                                           //ha nincs jobbra le blokkol� objektum
                            else mo.setDirection(9);                                    //akkor be�ll�tja az ir�ny�t
                        }
                        else {                                                          //ha sima k� van alatta
//                            logger.info("eddig eljutottam jobb");
                            if ((lifttest(x+1,y))&&(liftdir(x+1,y))){ //ha el�tte jobbra lejt� k� van
                                if (blocktest(x+1,y-1)){     //el�tte-felette blokkol� van
                                    mo.setDirection(3);
                                    mo.hitEvent((MapObject)field[x+1][y-1].get(0));
                                
                                }
                                else mo.setDirection(3);                                //nincs el�tte-felette blokkol� k�
                            }
                            else if(blocktest(x+1,y)){       //ha sima blokkol� objektum van el�tte
                                mo.setDirection(6);
                                mo.hitEvent((MapObject)field[x+1][y].get(0));
                            }
                            else{                                                       //ha nincs el�tte blokkol�
                                mo.setDirection(6);
                            }
                        }
                    }
                }
                else{//ha balra megy a lemming
                    if(!hastoptest(x,y+1)){                //ha nincs alatta talaj
                        mo.fallEvent();             //szol a lemmingnek, hogy esik
                        if(!hastoptest(x,y+1))mo.setDirection(10);         //be�ll�tja a lefel� ir�nyt, elt�rolva hogy jobbra megy majd tov�bb
                    }
                    else{                           //Ha van alatta talaj
                        
                        if (dir==10){
                            mo.setDirection(4);
                            mo.fallenEvent(); //Ha eddig esett, akkor foldeteres Eventet kuld a Lemmingnek
                        }
                        if ((lifttest(x,y+1))&&(liftdir(x,y+1))){  //ha jobbra lejt� k� van alatta
                            if (blocktest(x-1,y+1)){         //balra-le blokkol� k� van
                                mo.setDirection(7);                                     //ett�l f�ggetlen�l be�ll�tja az ir�ny�t
                                mo.hitEvent((MapObject)field[x-1][y+1].get(0));         //elk�ldi a hiteventet   
                            }                                                           //ha nincs jobbra le blokkol� objektum
                            else mo.setDirection(7);                                    //akkor be�ll�tja az ir�ny�t
                        }
                        else {                                                          //ha sima k� van alatta
//                            logger.info("eddig eljutottam bal");
                            if ((lifttest(x-1,y))&&(!liftdir(x-1,y))){             //ha el�tte balra lejt� k� van
                                if (blocktest(x-1,y-1)){     //el�tte-felette blokkol� van
                                    mo.setDirection(1);
                                    mo.hitEvent((MapObject)field[x-1][y-1].get(0));
                                
                                }
                                else mo.setDirection(1);                                //nincs el�tte-felette blokkol� k�
                            }
                            else if(blocktest(x-1,y)){       //ha sima blokkol� objektum van el�tte
                                
                                mo.setDirection(4);
                                mo.hitEvent((MapObject)field[x-1][y].get(0));
                            }
                            else{                                                       //ha nem blokkol� objektum van elotte
                                mo.setDirection(4);
                            }
                        }
                    }
                    
                }
		
	}
    /**
     * Az adott koordinatakon tartozkodo objektumok emelkedeset vizsgalja
     * @param x x koordinata
     * @param y Y koordinata
     * @return Emelkedik?
     */
	private boolean lifttest(int x,int y){
		boolean rt=false;
		try{
			for(int i=0;i<field[x][y].size();i++){
				MapObject mo = (MapObject)field[x][y].get(i);
				if(mo.isLift())rt=true;
			}
		}catch(Exception e){
			rt=false;
		}
		return rt;
	}
    /**
     * Az adott koordinatakon tartozkodo objektumok emelkedesenek iranyat adja vissza vizsgalja
     * @param x X koordinata
     * @param y Y koordinata
     * @return Emelkedesi irany
     */
	private boolean liftdir(int x,int y){
		boolean rt=false;
		try{
			for(int i=0;i<field[x][y].size();i++){
				MapObject mo = (MapObject)field[x][y].get(i);
				if(mo.isLift()) rt=mo.getLiftDir();
			}
		}catch(Exception e){
			rt=false;
		}
		return rt;
	}	
    /**
     * Az adott koordinatan levo Objektum Blokkolasi tulajdonsaganak tesztelese
     * @param x X koordinata
     * @param y Y koordinata
     * @return Blokkol?
     */
        private boolean blocktest (int x, int y){           //azt teszteli, hogy az adott mezon van e objektum
          try{
            if (field[x][y].size()==0) return false;
            return true;
          }
          catch(Exception e) {return false;}
        }
    /**
     * Az adott koordinatan levo Objektum hasTop tulajdonsaganak vizsgalata
     * @param x X  koordinata
     * @param y Y koordinata
     * @return Van teteje?
     */
        public boolean hastoptest (int x, int y){
            try{
               for(int i=0;i<field[x][y].size();i++){           //megnezi hogy az adott cellaban van e olyan elem, aminek van teteje	
			MapObject thing=(MapObject)field[x][y].get(i);
			if(thing.hasTop()){
				return true;  
			}
               }
            }
            catch(Exception e) {return false;}
            return false;
        }
        
    /**
     * A parameterul kapott Objectumot a megfelelo koordinatara teszi
     * @param x X koordinata
     * @param y Y koordinata
     * @param obj Objektum
     */
        private void putObject(int x, int y, MapObject obj) {
          try{
            if (field[x][y]==null) {
                field[x][y]=new LinkedList();
            }
            field[x][y].add(obj);
            obj.setGF(this);
//            logger.info("Objektum elhelyezve "+x+", " +y+" koordinatakon");
          }
          catch(Exception e){
              logger.info("Objektum kilepett a palyarol");
              numberOfLemmings--;           //elvileg nem csak lemming lephet ki, es akkor a numberOfLemmings rossz erteket ad
          }
        }
  //  public void killall(){
    //    throw (new GameOverException("killall",numberOfLemmings,numberOfWinners,digger, flying, builder, bomb, blocker));
    //}
        
    /**
     * A megadott Objektumot eltavolitja a palyarol
     * @param mo Objektum
     */
        private void removeObject(MapObject mo){
            int x=mo.getX();
            int y=mo.getY();
            field[x][y].remove(mo);
  //          logger.info("Objektum eltavolitva "+x+", " +y+" koordinatakrol");
            
        }
	 
	/**
     * Ez a fuggveny vegzi az egy utem alatt elvegzendo muveleteket. Minden lemminget mozgat, beallitja az iranyat, es tickeventet kuld mindennek
     */
	public void loop() throws GameOverException{
             
            if (numberOfLemmings==0) throw new GameOverException("Game Over");

            
            
            for (int k=0;k<mobjects.size();k++){
		    MapObject mo = (MapObject)mobjects.get(k);
		    if(mo.isMove())moveObject(mo);
            }
            
            for (int k=0;k<mobjects.size();k++){
		    MapObject mo = (MapObject)mobjects.get(k);
		    if(mo.isMove()){
			    testnextmove(mo);
			    logger.info("uj irany: "+mo.getDirection());
		    }
		    mo.tickEvent();
            }
            
            mobjects=new LinkedList();  //mobjects kiuritese
            
            for(int i=0;i<mx;i++)   //mobjects ujraepitese
                for (int j=0;j<my;j++){
                    if(field[i][j]!=null){
                        for (int k=0;k<field[i][j].size();k++){
                            MapObject mo=(MapObject)field[i][j].get(k);
                            mobjects.add(mo);
                        }
                    }
                }
            
		
	}
	 
	/**
     * A bementi sztringet ertelmezi
     * @param inp A string ami a parancsot tartalmazza
     * @throws fmglemmings.GameOverException 
     */
	public void input(String inp) throws GameOverException{
//		try{
		    StringTokenizer parser = new StringTokenizer(inp); 
		    String s = parser.nextToken();
		    if (s.equals("pause")) {
			if(paused)paused=false;
			else paused=true;
		    }
		    if (s.equals("tik")) {
			int n;   
			if(!paused){
				try{
					n = Integer.parseInt(parser.nextToken().trim());   
				} catch (Exception e){
					n = 1;
				}
				for(int i=0;i<n;i++)loop();
			}
		    }
		    if (s.equals("swap")) {
			int x = Integer.parseInt(parser.nextToken().trim());
			int y = Integer.parseInt(parser.nextToken().trim());   
                        try{ 
                          if (field[x][y].get(0) instanceof Lemming){
                           
                            String type = parser.nextToken();
                            if((type.equals("Lemming"))&&(getLemming(x,y)!=null)){	
        
                                setLemmingType(getLemming(x,y),new Lemming(1,1,1));
                                logger.info("Normal Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                buildmobjects();
                                
                            }
                            if(type.equals("BuilderLemming")){
                                if ((builder>0)&&(getLemming(x,y)!=null)){
                                    setLemmingType(getLemming(x,y),new BuilderLemming(1,1,1));
                                    builder--;
                                    logger.info("Epito Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                    buildmobjects();
                                
                                }
                        
                            }
                            if(type.equals("BlockerLemming")){
                                if ((blocker>0)&&(getLemming(x,y)!=null)){
                                    setLemmingType(getLemming(x,y),new BlockerLemming(1,1,1));
                                    blocker--;
                                    logger.info("Blokkolo Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                    buildmobjects();
                                
                                }
                        
                            }
                            if(type.equals("DiggerLemming")){
                                if ((digger>0)&&(getLemming(x,y)!=null)){
                                    setLemmingType(getLemming(x,y),new DiggerLemming(1,1,1));
                                    digger--;
                                    logger.info("Aso Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                    buildmobjects();
                                
                                }
                            }
                            if(type.equals("BomberLemming")){
                                if ((bomb>0)&&(getLemming(x,y)!=null)){
                                    setLemmingType(getLemming(x,y),new BombLemming(1,1,1));
                                    bomb--;
                                    logger.info("Robbano Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                    buildmobjects();
                                
                                }
                            }
                            if(type.equals("FlyingLemming")){
                                if ((flying>0)&&(getLemming(x,y)!=null)){
                                    setLemmingType(getLemming(x,y),new FlyingLemming(1,1,1));
                                    flying--;
                                    logger.info("Repulo Lemmingge valtoztatva "+x+", "+y+" koordinatakon");
                                    buildmobjects();
                                
                                }
                            }
                          }
                          else logger.info("Az adott koordinatakon nincs lemming");
                          
                        }
                        catch(Exception e){logger.info("Az adott koordinatakon nincs lemming");}
		    }
		    if (s.equals("stop")) {
//			logger.info("Palyan levo lemmingek:"+numberOfLemmings);    
//			logger.info("Celba ert lemmingek:"+numberOfWinners);
			throw new GameOverException("KillAll");
		    }
//		}catch(Exception e){
//			logger.warning("Szar van a palacsintaban");
//		}
	}
        
        public Lemming getLemming(int x,int y){
            try{
                if ((MapObject)field[x][y].get(0) instanceof Lemming)
                    return (Lemming)field[x][y].get(0);
            }
            catch(Exception e){logger.info("Az adott koordinatakon nincs lemming");};
            return null;
        }
    /**
     * a palya default konstruktora
     */
        public GameField(){
            mx = my = numberOfLemmings = numberOfWinners = digger = flying = builder = bomb = blocker = 0;
        }
	/**
     * A Lemming tipusat lecsereli a parameterben megadott lemmingre
     * @param from A regi lemming
     * @param to Az uj tipusu Lemming
     */
	
	private void setLemmingType(MapObject from,MapObject to) {
            int x=from.getX();
            int y=from.getY();
            int dir=from.getDirection();
            to.setX(x);
            to.setY(y);
            to.setDirection(dir);
         //   if(field[x][y].get(0) instanceof BlockerLemming){System.out.println("blocker");};
            putObject(x,y,to);
            removeObject(from);
     //       if(field[x][y].get(0) instanceof FlyingLemming){System.out.println("flying");};
       //     if(field[x][y].get(1) instanceof BuilderLemming){System.out.println("builder");};
            logger.info("Objektum kicserelve "+x+", " +y+" koordinatakon");
	}
	 
	/**
     * Elhalalozasi kerelem. A parameterul kapott lemminget megoli.
     * @see RequestListener#dieRequest()
     * @param mo ezt a MapObjectet fogja megolni
     */
	public void dieRequest(MapObject mo) {	
                setLemmingType(mo,new DeadLemming(1,1,1));
                logger.info("Lemming eltavolitva X:"+mo.getX()+" Y: "+mo.getY());
		removeObject(mo);
                numberOfLemmings--;
	}
	public void dieRequest(MapObject mo, boolean nodead){
		if(!nodead)setLemmingType(mo,new DeadLemming(1,1,1));
		logger.info("Lemming eltavolitva X:"+mo.getX()+" Y: "+mo.getY());
		removeObject(mo);
                numberOfLemmings--;
	}
	 
	/**
     * Epitesi kerelem
     * @param mo Ez ala a lemming ala epit hidat
     * @see RequestListener#buildRequest()
     */
	public void buildRequest(MapObject mo) {
		int x,y;
		x=mo.getX();
		y=mo.getY()+1;
		putObject(x,y, new Bridge(x,y,0,false));
		logger.info("egy hidelem kesz");
	}
	 
	/**
     * Szoszedos mezok megkeresese, nekik boomevent elkuldese
     * @see RequestListener#boomRequest()
     * @param x x koordinata
     * @param y Y koordinata
     */
	private void boomsender(int x, int y){
            try{
		if(field[x][y]!=null){
//			Iterator iter = field[x][y].iterator();
//			while(iter.hasNext()){
//				MapObject mo = (MapObject)iter.next();
//				mo.bombEvent();
//			}
			int j = field[x][y].size();
			for(int i=0;i<j;i++){
				MapObject thing = (MapObject)field[x][y].get(0);
				thing.bombEvent();
			}
		}
            }
            catch(Exception e) {};
	}
    /**
     * Robbanasi kerelem
     * @param mo Ez az Objektum robbant fel
     */
	public void boomRequest(MapObject mo) {
		int x,y;
		x=mo.getX();
		y=mo.getY();
		boomsender(x,y);
		boomsender(x+1,y);
		boomsender(x+1,y+1);
		boomsender(x+1,y-1);
		boomsender(x,y+1);
		boomsender(x,y-1);
		boomsender(x-1,y);
		boomsender(x-1,y-1);
		boomsender(x-1,y+1);
//		removeObject(mo);
//		logger.info(mo.toString() + "felrobbant");
	}
	
	/**
     * Eltavolitasi kerelem
     * @see RequestListener#removeRequest()
     * @param mo az adott objektumot kell eltavolitani a jatekmezorol
     */
	public void removeRequest(MapObject mo) {
		if((mo.isDestructable())&&!(mo instanceof Lemming)){
			logger.info("Objektum eltavolitasra kerult X:"+mo.getX()+" Y:"+mo.getY());
			removeObject(mo);
		}
	}
	 
	/**
     * Visszavaltozasi kerelem
     * @see RequestListener#changeRequest()
     * @param mo ez az objectum valtozik vissza normal lemmingge.
     */
	public void changeRequest(MapObject mo) {
                MapObject uj=new Lemming(1,1,1);
		setLemmingType(mo,uj);
                testnextmove(uj);
	}
	 
	/**
	 * Gyozelmi kerelem
	 * @param mo Parmeterben kapja melyik objektum nyer
	 */
	public void winRequest(MapObject mo) {
		numberOfWinners++;
		numberOfLemmings--;
		this.removeObject(mo);
		logger.info("Egy lemming a celba ert");
//		if(numberOfLemmings==0) {
//			logger.info("GAME OVER - elfogytak a lemmingek");
//		}else logger.info("A jatekban maradt lemmingek szama:"+numberOfLemmings);
	}
	 
	/**
	 * Megfordulasi kerelem
	 * @param mo Parameterben kapja melyik objektum akar megfordulni
//	 */
	public void turnRequest(MapObject mo) {
                int dir=mo.getDirection();
                if ((dir==3)||(dir==6)||(dir==9)||(dir==11)){
                    mo.setDirection(4);
                }
                else mo.setDirection(6);
                testnextmove(mo);
		logger.info("Fordulas");
	}

    /**
     * Lemmingletrehozasi kerelem
     * @param mo ennek az objektumnak a koordinataira hozza letre az uj lemminget
     */
	public void bornRequest(MapObject mo) {
//		numberOfLemmings++;
                MapObject uj=new Lemming(mo.getX(),mo.getY(),6);
		putObject(mo.getX(),mo.getY(),uj);
                testnextmove(uj);
	} 
}
 
